import { instantiate, Prefab } from "cc";
import ResLoader from "./common/loader/ResLoader";
import { EventDispatcher } from "./event";
import { Injector } from "./inject";
import { Context } from "./mvcs/Context";
import { IViewFactory, View_Factory_Adapter_Tag } from "./mvcs/impl/ViewMap";
import SoundManager from './sound/SoundManager';
import TaskManager from "./task/TaskManager";
import UIManager from "./view/UIManager";

class ViewAdapterFactory implements IViewFactory {
    async createViewByResourceId(path: string, viewName: string) {
        let prefab: Prefab = await app.res.loadASync(path, Prefab);
        let node = instantiate(prefab);
        return node;
    }
}

class App {
    context: Context = null;

    ui: UIManager = null;
    res: ResLoader = null;
    task: TaskManager = null;
    sound: SoundManager = null;
    event: EventDispatcher = null;

    load() {
        this.event = Injector.default.getInstance(EventDispatcher);

        // mvcs context
        this.context = Injector.default.getInstance(Context);

        // manager
        this.ui = Injector.default.getInstance(UIManager);
        this.res = Injector.default.getInstance(ResLoader);
        this.task = Injector.default.getInstance('TaskManager');
        this.sound = Injector.default.getInstance(SoundManager);

        // view adapter
        this.context.injector.mapClass(View_Factory_Adapter_Tag, ViewAdapterFactory);

        // global command
        this.context.commandMap.mapCommand('Evt_Switch_Scene', 'SwitchSceneCommand');
        this.context.commandMap.mapCommand('Evt_Switch_View', 'SwitchViewCommand');
        this.context.commandMap.mapCommand('Evt_Show_Toast', 'ShowToastCommand');


        // startup
        this.context.startup();
    }

    unload() {

    }
}

export const app = new App;